/*************************************************
* Title：TinyToolKit
* Author：Opportunity 
* Describe：实现UDP消息的广播和接收
* CreateTime：2020-08-13 10:52:55
* Version：1.0
* Modify Recorder：
*************************************************/

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using TinyToolKit.Timer;
using UnityEngine;

namespace TinyToolKit.Network
{
    [Serializable]
    public class BroadcastPacket
    {
        public string ip;
        public int port;
        public string productName;
        public string checkCode;
    }

    public class NetworkDiscoveryHelper
    {
        private UdpBroadcast _udpBroadcast;
        private UdpReceive _udpReceive;
        private List<string> _addressList;
        private string _productName;
        private int _port;

        #region Public Func

        public NetworkDiscoveryHelper() 
        {
            _productName = Application.productName;
            _addressList = TinyUtility.Network.ScanLocalAddress();
            _port = TinyUtility.Network.GetRandomPort();
        }

        /// <summary>
        /// 获取本地IP地址
        /// </summary>
        /// <returns>返回IP地址的字符串</returns>
        public string LocalIp => _addressList.Count == 0 ? string.Empty : _addressList[0];
        public int TcpPort => _port;

        /// <summary>
        /// 开始UDP消息广播
        /// </summary>
        /// <param name="udpPort">广播地址的端口号</param>
        /// <param name="interval">广播的时间间隔</param>
        /// <returns>是否开始UDP广播成功</returns>
        public bool StartBroadcast(int udpPort, float interval,Action<BroadcastPacket> onBroadcastFeedback)
        {
            BroadcastPacket packet = new BroadcastPacket
            {
                ip = LocalIp,
                port = udpPort,
                productName = _productName
            };
            
            _udpBroadcast = new UdpBroadcast(packet,interval,onBroadcastFeedback);
            return _udpBroadcast.StartUdpBroadcast();
        }

        /// <summary>
        /// 开始UDP接收消息
        /// </summary>
        /// <param name="udpPort">广播地址的端口号</param>
        /// <param name="tcpPort">用于发送的TCP连接端口号</param>
        /// <returns>是否成功开始接收消息</returns>
        public bool StartReceive(int udpPort,string checkCode,Action<BroadcastPacket> onReceivedMsg)
        {
            BroadcastPacket packet = new BroadcastPacket
            {
                ip = LocalIp,
                port = _port,
                productName = _productName,
                checkCode = checkCode
            };
            
            _udpReceive = new UdpReceive(packet,onReceivedMsg);
            return _udpReceive.StartUdpReceive(udpPort);
        }

        /// <summary>
        /// 关闭UDP广播
        /// </summary>
        public void CloseBroadcast()
        {
            _udpBroadcast?.Close();
        }
        
        /// <summary>
        /// 关闭UDP接收数据
        /// </summary>
        public void CloseReceive()
        {
            _udpReceive?.Close();
        }

        #endregion
    }
}